#ifndef __RESOURCE_HPP__
#define __RESOURCE_HPP__

namespace gdl
{

  class ResourceBase
  {
  public:
    ////////////////////////////////////////////////////////////
    /// Default constructor.
    ////////////////////////////////////////////////////////////
    ResourceBase();
    ////////////////////////////////////////////////////////////
    /// Copy constructor.
    ////////////////////////////////////////////////////////////
    ResourceBase(ResourceBase const & right);

    ////////////////////////////////////////////////////////////
    /// Default destructor.
    ////////////////////////////////////////////////////////////
    virtual ~ResourceBase();
    ////////////////////////////////////////////////////////////
    /// Overloading of the assignment operator.
    ////////////////////////////////////////////////////////////
    ResourceBase& operator=(ResourceBase const &);

  protected:
    ////////////////////////////////////////////////////////////
    /// Check if the data pointer can be destroyed.
    ////////////////////////////////////////////////////////////
    void check_destroy();

  private:
    ////////////////////////////////////////////////////////////
    /// Destroy the data pointer.
    ////////////////////////////////////////////////////////////
    virtual void destroy() = 0;
    ////////////////////////////////////////////////////////////
    /// Increase the reference counter.
    ////////////////////////////////////////////////////////////
    void incCount();
    ////////////////////////////////////////////////////////////
    /// Decrease the reference counter.
    ////////////////////////////////////////////////////////////
    void decCount();

    int* counter_;
  };

  template <typename Type>
  class Resource : private ResourceBase
  {
  public:
    ////////////////////////////////////////////////////////////
    /// Explicit constructor.
    ///
    /// \param[in] val The pointer on a resource.
    ////////////////////////////////////////////////////////////
    explicit Resource(Type* val);
    ////////////////////////////////////////////////////////////
    /// Copy constructor.
    ///
    /// \param[in] right Resource to copy.
    ////////////////////////////////////////////////////////////
    Resource(Resource const &);
    ////////////////////////////////////////////////////////////
    /// Overloading of the assignment operator.
    ///
    /// \return An reference on the Resource instance.
    ////////////////////////////////////////////////////////////
    Resource& operator=(Resource const &);
    ////////////////////////////////////////////////////////////
    /// Default destructor.
    ////////////////////////////////////////////////////////////
    virtual ~Resource();

    ////////////////////////////////////////////////////////////
    /// Check if the resource is valid.
    ///
    /// \return If valid, true is returned.
    /// Otherwise, false is returned.
    ////////////////////////////////////////////////////////////
    bool	isValid() const;

    ////////////////////////////////////////////////////////////
    /// Overloading of the member operator.
    ////////////////////////////////////////////////////////////
    Type* operator->();
    ////////////////////////////////////////////////////////////
    /// Overloading of the indirection operator.
    ////////////////////////////////////////////////////////////
    Type& operator*();

  protected:
    Type* data_; //Template type to point the data

    ////////////////////////////////////////////////////////////
    /// Reset the data.
    ////////////////////////////////////////////////////////////
    void HardReset();

  private:
    ////////////////////////////////////////////////////////////
    /// Destroy the data.
    ////////////////////////////////////////////////////////////
    virtual void destroy();
  };
}

#endif /* __RESOURCE_HPP__ */
